package cn.com.easy.pay.alipay.union.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.com.easy.exception.BusinessException;
import cn.com.easy.pay.alipay.union.config.AlipayUnionConfig;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;

/**
 * (统一收单线下交易查询)基础控制器,详参：
 * https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905
 * .0.0.VlCdOG&docType=4&apiId=757
 * 
 * @author nibili 2017年5月16日
 * 
 */
public abstract class AlipayTradeQueryBaseController {

	private Logger logger = LoggerFactory.getLogger(AlipayTradeQueryBaseController.class);

	/**
	 * 阿里配置参数
	 * 
	 * @param httpServletRequest
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年5月16日
	 */
	public abstract AlipayUnionConfig getAlipayConfig(HttpServletRequest httpServletRequest) throws BusinessException;

	/**
	 * 统一收单线下交易查询 参数，详参：
	 * https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905
	 * .0.0.VlCdOG&docType=4&apiId=757
	 * 
	 * @param httpServletRequest
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年5月16日
	 */
	public abstract AlipayTradeQueryModel getAlipayTradeQueryModel(HttpServletRequest httpServletRequest) throws BusinessException;

	/**
	 * 退款成功<br/>
	 * 返回的对实会被序列化，传递到客户端
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param notifyParam
	 * @throws BusinessException
	 * @author nibili 2017年4月7日
	 */
	public abstract Object successCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AlipayTradeQueryResponse response)
			throws BusinessException;

	/**
	 * 错误回调
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param response
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年5月16日
	 */
	public abstract Object failCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AlipayTradeQueryResponse response) throws BusinessException;

	/**
	 * 发生本地处理异常
	 * 
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param response
	 * @return
	 * @throws BusinessException
	 * @author nibili 2017年5月16日
	 */
	public abstract Object errorCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Exception exception);

	@RequestMapping("/query.json")
	public void refund(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
		try {
			//
			AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
			request.setBizModel(getAlipayTradeQueryModel(httpServletRequest));
			//
			AlipayUnionConfig alipayConfig = getAlipayConfig(httpServletRequest);
			// 实例化客户端
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayUnionConfig.URL, alipayConfig.getApp_id(), alipayConfig.getRsa_private_key(), AlipayUnionConfig.FORMAT,
					AlipayUnionConfig.CHARSET, alipayConfig.getAlipay_public_key(), alipayConfig.getSigntype());
			AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.execute(request);
			if (alipayTradeQueryResponse.isSuccess()) {
				// System.out.println("调用成功");
				this.successCallback(httpServletRequest, httpServletResponse, alipayTradeQueryResponse);
			} else {
				// System.out.println("调用失败");
				this.failCallback(httpServletRequest, httpServletResponse, alipayTradeQueryResponse);
			}
		} catch (AlipayApiException alipayApiException) {
			logger.error("支付宝异常", alipayApiException);
			this.errorCallback(httpServletRequest, httpServletResponse, alipayApiException);
		} catch (Exception ex) {
			logger.error("", ex);
			this.errorCallback(httpServletRequest, httpServletResponse, ex);
		}
	}
}
